package ink.carnation.imtalk.websocket;

import com.alibaba.fastjson.JSONObject;
import ink.carnation.imtalk.exception.ArgumentException;
import ink.carnation.imtalk.exception.IMException;
import ink.carnation.imtalk.model.enums.MessageType;
import ink.carnation.imtalk.model.message.MessageRequest;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;


@Slf4j
@ServerEndpoint("/websocket/chat/{userId}")
@Component
public class WebSocketServer {

    /**
     * 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
     */
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    /**
     * concurrent包的线程安全Map，用来存放每个客户端对应的MyWebSocket对象。
     */
    public static Map<Integer, Session> sessionMap = new ConcurrentHashMap<>();



    private Integer userId;

    private Session session;

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam  ("userId") Integer userId) {
        if(!sessionMap.containsKey(userId)){
            sessionMap.put(userId,session);
            onlineCount.getAndIncrement();
        }
        log.info("用户连接:"+userId+",当前在线人数为:" + onlineCount.get());

        try {
            sendMessage("连接成功",session);
        } catch (IOException e) {
            log.error("用户:"+userId+",网络异常!!!!!!");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam(value = "userId") Integer userId,Session session) throws IOException {
        sessionMap.remove(userId);
        onlineCount.decrementAndGet();
        session.close();
        log.info("用户退出:"+userId+",当前在线人数为:" + onlineCount.get());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message,Session session) throws IOException {
        log.info("消息传递记录 {}",message);
        MessageRequest messageRequest = JSONObject.parseObject(message, MessageRequest.class);
        MessageType messageType = messageRequest.getMessageType();
        if(messageType == null){
            throw new ArgumentException("消息类型不能为空");
        }
        switch (messageType){
            case PRIVATE_CHAT:{
                //私聊传递消息
                Integer friendId = messageRequest.getOtherId();
                if(friendId ==null) {
                    throw new ArgumentException("参数异常");
                }
                if(sessionMap.containsKey(friendId)) {
                    sendMessage(message,sessionMap.get(friendId));
                }
            }break;
            case ADD_FRIEND:{
                throw new IMException("待开发",405);

            }
            case GROUP_CHAT:{
                //获取群聊号
                Integer groupId = messageRequest.getOtherId();
                //查询存在用户
                List<Integer> userList = null;
                //依次发送消息
                userList.stream()
                        .filter((x)->sessionMap.containsKey(x))
                        .forEach((x)-> {
                            try {
                                sendMessage((String) messageRequest.getContent(),sessionMap.get(x));
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        });

            }
        }
    }
    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {

        error.printStackTrace();
    }
    /**
     * 实现服务器主动推送
     */
    private void sendMessage(String message,Session session) throws IOException {
        session.getBasicRemote().sendText(message);
    }


}